from fastapi import APIRouter, Depends, Request
from fastapi.encoders import jsonable_encoder

from ... import settings
from ...common.render_template import templates
from ...common.user_manager import manager
from ...models import Power, User
from ...schemas.admin_power import MenuOut
from ...models.admin_log import LoginLog
from ...models.admin_log import OperationLog
from ...models.admin_photo import Photo
from datetime import datetime, timedelta

route = APIRouter(prefix="/rights", tags=["权限管理"])


@route.get("/configs", name="system.rights.configs", dependencies=[Depends(manager)], summary="获取系统配置")
def configs():
    """
    # 渲染配置
    :return:
    """
    # 网站配置
    config = dict(
        logo={
            # 网站名称
            "title": settings.SYSTEM_NAME,
            # 网站图标
            "image": "/static/system/admin/images/logo.png",
            # 菜单配置
        },
        menu={
            # 菜单数据来源
            "data": "/system/rights/menu",
            "collaspe": False,
            # 是否同时只打开一个菜单目录
            "accordion": True,
            "method": "GET",
            # 是否开启多系统菜单模式
            "control": False,
            # 顶部菜单宽度 PX
            "controlWidth": 500,
            # 默认选中的菜单项
            "select": "0",
            # 是否开启异步菜单，false 时 data 属性设置为菜单数据，false 时为 json 文件或后端接口
            "async": True,
        },
        tab={
            # 是否开启多选项卡
            "enable": True,
            # 切换选项卡时，是否刷新页面状态
            "keepState": True,
            # 是否开启 Tab 记忆
            "session": True,
            # 预加载
            "preload": False,
            # 最大可打开的选项卡数量
            "max": 30,
            "index": {
                # 标识 ID , 建议与菜单项中的 ID 一致
                "id": "10",
                # 页面地址
                "href": "/system/rights/welcome",
                # 标题
                "title": "首页",
            },
        },
        theme={
            # 默认主题色，对应 colors 配置中的 ID 标识
            "defaultColor": "2",
            # 默认的菜单主题 dark-theme 黑 / light-theme 白
            "defaultMenu": "dark-theme",
            # 是否允许用户切换主题，false 时关闭自定义主题面板
            "allowCustom": True,
        },
        colors=[
            {"id": "1", "color": "#2d8cf0"},
            {"id": "2", "color": "#5FB878"},
            {"id": "3", "color": "#1E9FFF"},
            {"id": "4", "color": "#FFB800"},
            {"id": "5", "color": "darkgray"},
        ],
        links=settings.SYSTEM_PANEL_LINKS,
        other={
            # 主页动画时长
            "keepLoad": 0,
            # 布局顶部主题
            "autoHead": False,
        },
        header={"message": "/system/rights/message"},
    )
    return jsonable_encoder(config)


# 消息
@route.get("/message", summary="获取消息")
def message():
    return dict(
        code=200,
        data=[
            {
                "id": 1,
                "title": "通知",
                "children": [
                    {
                        "id": 11,
                        "avatar": "https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png",
                        "title": "你收到了 14 份新周报",
                        "context": "这是消息内容。",
                        "form": "就眠仪式",
                        "time": "刚刚",
                    },
                    {
                        "id": 12,
                        "avatar": "https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png",
                        "title": "曲妮妮 已通过第三轮面试",
                        "context": "这是消息内容。",
                        "form": "就眠仪式",
                        "time": "刚刚",
                    },
                    {
                        "id": 11,
                        "avatar": "https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png",
                        "title": "可以区分多种通知类型",
                        "context": "这是消息内容。",
                        "form": "就眠仪式",
                        "time": "刚刚",
                    },
                    {
                        "id": 12,
                        "avatar": "https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png",
                        "title": "左侧图标用于区分不同的类型",
                        "context": "这是消息内容。",
                        "form": "就眠仪式",
                        "time": "刚刚",
                    },
                    {
                        "id": 11,
                        "avatar": "https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png",
                        "title": "内容不要超过两行字",
                        "context": "这是消息内容。",
                        "form": "就眠仪式",
                        "time": "刚刚",
                    },
                ],
            },
            {
                "id": 2,
                "title": "消息",
                "children": [
                    {
                        "id": 11,
                        "avatar": "https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png",
                        "title": "你收到了 14 份新周报",
                        "context": "这是消息内容。",
                        "form": "就眠仪式",
                        "time": "刚刚",
                    },
                    {
                        "id": 12,
                        "avatar": "https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png",
                        "title": "曲妮妮 已通过第三轮面试",
                        "context": "这是消息内容。",
                        "form": "就眠仪式",
                        "time": "刚刚",
                    },
                    {
                        "id": 11,
                        "avatar": "https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png",
                        "title": "可以区分多种通知类型",
                        "context": "这是消息内容。",
                        "form": "就眠仪式",
                        "time": "刚刚",
                    },
                    {
                        "id": 12,
                        "avatar": "https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png",
                        "title": "左侧图标用于区分不同的类型",
                        "context": "这是消息内容。",
                        "form": "就眠仪式",
                        "time": "刚刚",
                    },
                    {
                        "id": 11,
                        "avatar": "https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png",
                        "title": "内容不要超过两行字",
                        "context": "这是消息内容。",
                        "form": "就眠仪式",
                        "time": "刚刚",
                    },
                ],
            },
            {"id": 3, "title": "代办", "children": []},
        ],
    )


# 菜单
@route.get("/menu", summary="获取菜单")
async def menu(current_user: User = Depends(manager)):
    # 根据用户身份获取权限列表
    if current_user.username != settings.SUPERADMIN:
        powers = await get_user_powers(current_user)
    else:
        powers = await Power.filter(enable=1).all()

    # 使用通用函数处理权限数据并构建菜单
    return await build_menu_tree(powers)


# 控制台页面
@route.get("/welcome", dependencies=[Depends(manager)], include_in_schema=False)
async def welcome(request: Request):
    # 计算今日访问和总流量（登录记录数）
    now = datetime.now()
    start_of_day = datetime(year=now.year, month=now.month, day=now.day)
    start_of_next_day = start_of_day + timedelta(days=1)
    today_visits = await LoginLog.filter(create_time__gte=start_of_day, create_time__lt=start_of_next_day).count()
    total_visits = await LoginLog.all().count()
    # 今日提交（操作日志：POST/PUT/DELETE/PATCH）
    today_submissions = await OperationLog.filter(
        create_time__gte=start_of_day,
        create_time__lt=start_of_next_day,
        method__in=settings.OPERATION_RECORD_METHOD,
    ).count()
    # 新增图片（今日上传的图片数量）
    today_uploads = await Photo.filter(create_time__gte=start_of_day, create_time__lt=start_of_next_day).count()
    return templates.TemplateResponse(
        "system/analysis/main.html",
        {
            "request": request,
            "today_visits": today_visits,
            "total_visits": total_visits,
            "today_submissions": today_submissions,
            "today_uploads": today_uploads,
        },
    )


async def get_user_powers(user: User) -> list[Power]:
    """获取用户的权限列表"""
    await user.fetch_related("roles")
    powers = []

    for role in user.roles:
        # 跳过未启用的角色
        if not role.enable:
            continue

        # 获取角色权限
        await role.fetch_related("powers")
        for power in role.powers:
            # 跳过未启用的权限和非菜单类型
            if not power.enable or int(power.type) not in [0, 1]:
                continue

            # 避免重复添加
            if power not in powers:
                powers.append(power)

    return powers


async def build_menu_tree(powers: list[Power]) -> list[dict]:
    """构建菜单树结构"""
    # 使用Pydantic模型进行序列化
    power_dicts = [MenuOut.model_validate(power).model_dump(by_alias=False) for power in powers]

    # 按parent_id和id排序，确保父节点在前
    power_dicts.sort(key=lambda x: (x["parent_id"], x["id"]), reverse=True)

    # 使用字典构建菜单树
    menu_dict = {}
    for item in power_dicts:
        item_id = item["id"]
        parent_id = item["parent_id"]

        # 如果当前节点有子节点，添加到children字段
        if item_id in menu_dict:
            item["children"] = menu_dict[item_id]
            item["children"].sort(key=lambda x: x["sort"])
            del menu_dict[item_id]

        # 将当前节点添加到父节点的children列表中
        if parent_id not in menu_dict:
            menu_dict[parent_id] = [item]
        else:
            menu_dict[parent_id].append(item)

    # 返回根节点(父节点ID为0)的菜单，按sort字段排序
    root_menu = menu_dict.get(0, [])
    root_menu.sort(key=lambda x: x["sort"])

    return jsonable_encoder(root_menu)
